//
//  OCImage.m
//  OpenGLGame
//
//  Created by Nguyen Cong Huy on 11/12/12.
//  Copyright (c) 2012 UIT. All rights reserved.
//

#import "OCImage.h"
#include "LBFramebuffer.h"
@implementation OCImage
@synthesize imageData;
@synthesize width;
@synthesize height;
@synthesize byteInAPixel;

- (id)initWithFileName:(NSString*)fileName{
    if(self = [super init]){
        UIImage* img = [UIImage imageNamed:fileName];
        CGImageRef cgImg = [img CGImage];
        
        
        width = CGImageGetWidth(cgImg);
        height = CGImageGetHeight(cgImg);
        if(width == 0 || height == 0) return nil;
        byteInAPixel = 4;
        
        
        
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        imageData = (GLubyte*)malloc(height*width*byteInAPixel);
        int bitPerComponent = 8;
        int bytePerRow = byteInAPixel*width;
        CGContextRef context = CGBitmapContextCreate(imageData, width, height, bitPerComponent, bytePerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
        if (!context) {
            context = CGBitmapContextCreate(imageData, width, height, bitPerComponent, bytePerRow, colorSpace, CGImageGetBitmapInfo(cgImg));
        }
        CGContextSetBlendMode(context, kCGBlendModeCopy);
        CGColorSpaceRelease(colorSpace);
        CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgImg);
        CGContextRelease(context);
        
        for(int i = 0; i < height/2; i++){
            int topIndex = i;
            int bottomIndex = height - 1 -i;
            GLubyte* topPointer = imageData + topIndex*(int)width*byteInAPixel;
            GLubyte* bottomPointer = imageData + bottomIndex*(int)width*byteInAPixel;
            GLubyte temp[(int)width*byteInAPixel];
            
            memcpy(temp, topPointer, sizeof(GLubyte)*(int)width*byteInAPixel);
            memcpy(topPointer, bottomPointer, (int)width*byteInAPixel);
            memcpy(bottomPointer, temp, (int)width*byteInAPixel);
        }
    }
    
    return self;
}

- (void)dealloc{
    free(imageData);
    imageData = 0;
    [super dealloc];
}

- (id)initWithTexture:(LBTexture*) texture{
    if(self = [super init]){
        LBFramebuffer* fbo = new LBFramebuffer(texture);
        free(imageData);
        imageData = (GLubyte*)malloc(texture->getWidth()*texture->getHeight()*4);
        fbo->imageData(&imageData);
        width = texture->getWidth();
        height = texture->getHeight();
        byteInAPixel = texture->getByteInAPixel();
    }
    return self;
}

- (UIImage*)createUiImage{
    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, imageData, width*height*byteInAPixel, NULL);
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    
    CGImageRef iref =  CGImageCreate(width, height, 8, 32, width*4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast, ref, NULL, true, kCGRenderingIntentDefault);
    
    NSInteger widthInPoint, heightInPoint;
    
    widthInPoint = width;
    heightInPoint = height;
        
    UIGraphicsBeginImageContext(CGSizeMake(widthInPoint, heightInPoint));
    
    CGContextRef currcontext = UIGraphicsGetCurrentContext();
    
    CGContextSetBlendMode(currcontext, kCGBlendModeCopy);
    CGContextDrawImage(currcontext, CGRectMake(0, 0, widthInPoint, heightInPoint), iref);
    
    UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    CFRelease(ref);
    CFRelease(colorspace);
    CGImageRelease(iref);
    
    return image;
}

- (void)saveToPngFile:(NSString*)filePath{
    UIImage* uiImage = [self createUiImage];
    [UIImagePNGRepresentation(uiImage) writeToFile:filePath atomically:YES];
    //[uiImage release];
}



- (id)initWithUIImage:(UIImage*)uiImage{
    if(self = [super init]){
        CGImageRef cgImg = [uiImage CGImage];
        
        width = CGImageGetWidth(cgImg);
        height = CGImageGetHeight(cgImg);
        if(width == 0 || height == 0) return nil;
        byteInAPixel = 4;
        
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        imageData = (GLubyte*)malloc(height*width*byteInAPixel);
        int bitPerComponent = 8;
        int bytePerRow = byteInAPixel*width;
        CGContextRef context = CGBitmapContextCreate(imageData, width, height, bitPerComponent, bytePerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
        if (!context) {
            context = CGBitmapContextCreate(imageData, width, height, bitPerComponent, bytePerRow, colorSpace, CGImageGetBitmapInfo(cgImg));
        }
        CGColorSpaceRelease(colorSpace);
        CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgImg);
        CGContextRelease(context);
        
        for(int i = 0; i < height/2; i++){
            int topIndex = i;
            int bottomIndex = height - 1 -i;
            GLubyte* topPointer = imageData + topIndex*(int)width*byteInAPixel;
            GLubyte* bottomPointer = imageData + bottomIndex*(int)width*byteInAPixel;
            GLubyte temp[(int)width*byteInAPixel];
            
            memcpy(temp, topPointer, sizeof(GLubyte)*(int)width*byteInAPixel);
            memcpy(topPointer, bottomPointer, (int)width*byteInAPixel);
            memcpy(bottomPointer, temp, (int)width*byteInAPixel);
            
        }
        
    }
    return self;
}
@end
